﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpModelInterface.h"
#include "INoElementIdDbObject.h"
#include "DbDataSchema.h"

namespace gcmp {
    class IParameter;
    class IParameterValueStorage;
    class IElement;
    class UniIdentity;

    /// \brief Element参数定制器接口
    ///
    ///除非有特殊需求，否则该接口内无需对平台默认参数（比如定位、名称参数）做额外的处理
    class GCMP_MODEL_INTERFACE_EXPORT IElementParametersCustomizer : public INoElementIdDbObject
    {
        DEFINE_CAST_DERIVED(gcmp::IElementParametersCustomizer, gcmp::INoElementIdDbObject)
    public:
        /// \brief 生成默认的元素参数定制器
        /// \param pDocument 所属文档
        /// \param ownerElementId 所属元素Id
        /// \return 默认的元素参数定制器
        static OwnerPtr<IElementParametersCustomizer> CreateDefaultCustomizer(const IElement* pElement);

        /// \brief 生成默认的Instance参数定制器
        ///
        /// \param pElement 所属元素
        /// \return 默认的Instance参数定制器
        static OwnerPtr<IElementParametersCustomizer> CreateDefaultInstanceParametersCustomizer(const IElement* pElement);

        /// \brief 通过参数id来获得原生参数，此参数id文档唯一。
        ///
        ///  通过该接口进行相关操作时， 应当明确自己是否需要平台相关的参数(比如定位参数、名称参数等)，
        ///  如果是， 需要使用IElementParameter::GetNativeParameter
        /// \see IElementParameters::GetNativeParameter
        ///
        /// \param parameterId 文档唯一的参数id
        /// \return 返回Parameter对象，如果失败则返回空的OwnerPtr。
        virtual OwnerPtr<IParameter> GetNativeParameter(int parameterId) const = 0;

        /// \brief 设置原生参数， 仅设置用户自定义的
        ///
        ///  通过该接口进行相关操作时， 应当明确自己是否需要平台相关的参数(比如定位参数、名称参数等)，
        ///  如果是， 需要使用IElementParameter::SetNativeParameter
        /// \see IElementParameters::SetNativeParameter
        ///
        /// \param parameter 输入要设置的参数对象
        /// \param errorMessage 输出错误信息，为可选参数。失败的情况下获取错误信息。
        /// \return 返回true表示设置成功，否则表示设置失败。如果失败可以通过errorMessage参数获取错误信息。
        virtual bool SetNativeParameter(const IParameter *pParameter, std::wstring* errorMessage = nullptr) = 0;

        /// \brief 报告原生参数
        ///
        ///  通过该接口进行相关操作时， 如需名称、定位等相关参数， 需要自己通过该接口报出
        ///
        /// \param parameterIds 元素拥有的原生参数Id集合
        /// \return void
        virtual void ReportParameterDefinitions(std::vector<int>* parameterIds) const = 0;

        /// \brief 获取参数是否可以被修改
        ///
        ///  通过该接口进行相关操作时， 应当明确自己是否需要平台相关的参数(比如定位参数、名称参数等)，
        ///  如果是， 需要使用IElementParameter::IsParameterModifiable
        /// \see IElementParameters::IsParameterModifiable
        ///
        /// \param parameterId 文档唯一的参数id
        /// \return 返回true表示参数可修改，否则返回false。
        virtual bool IsParameterModifiable(int parameterId) const = 0;

        /// \brief 是否是预设的参数
        /// 
        /// \param parameterDefinitionUid 参数定义Uid
        /// \return 返回true表示是预设参数，否则返回false
        virtual bool IsPresetParameter(const UniIdentity& parameterDefinitionUid) const = 0;

        /// \brief 对传入参数值，根据不同的参数类型以及业务场景进行调整过滤
        ///
        /// \param parameterDefinitionUid 参数定义数据Uid
        /// \param values 需要过滤调整的参数值引用
        virtual void FilterParameterValues(const UniIdentity& parameterDefinitionUid, 
            std::vector<OwnerPtr<IParameterValueStorage>>& values) const = 0;
    };

}// namespace gcmp


